package com.mvc.business.web;

import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.extremecomponents.table.limit.Limit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import com.mvc.PdfUtils;
import com.mvc.ProjectUtils;
import com.mvc.base.model.Company;
import com.mvc.base.model.UserNotice;
import com.mvc.base.service.CustomerManager;
import com.mvc.business.model.Order;
import com.mvc.business.service.OrderManager;
import com.mvc.config.ApplicationConfig;
import com.mvc.framework.dao.PropertyFilter;
import com.mvc.framework.model.BaseEntity;
import com.mvc.framework.service.DictionaryFacade;
import com.mvc.framework.service.PageManager;
import com.mvc.framework.util.DomainUtils;
import com.mvc.framework.util.FileUpDownUtils;
import com.mvc.framework.util.FrameworkContextUtils;
import com.mvc.framework.util.PageSearch;
import com.mvc.framework.util.PageUtils;
import com.mvc.framework.web.PageController;
import com.mvc.portal.service.CUserManager;
import com.mvc.portal.service.NotificationManager;
import com.mvc.security.model.User;
import com.mvc.security.service.UserManager;

@Controller
@RequestMapping("order")
public class OrderController extends PageController<Order> {

	private static final Logger	LOGGER	= Logger.getLogger(OrderController.class);

	@Autowired
	private OrderManager	    orderManager;

	@Autowired
	private UserManager<User>	userManager;

	@Autowired
	private CustomerManager	    customerManager;

	@Autowired
	private NotificationManager	notificationManager;

	@Autowired
	private DictionaryFacade	dictionaryFacade;

	@Autowired
	private CUserManager	    cUserManager;

	protected String handlePage(HttpServletRequest request, PageSearch page) {
		pageSetting(request);
		return super.handlePage(request, page);
	}

	protected void pageSetting(HttpServletRequest request) {
		request.setAttribute("users", userManager.getAll());
		request.setAttribute("action", "page");
		request.setAttribute("customers", customerManager.getAll());
		request.setAttribute("template", ApplicationConfig.getTemplate());
	}

	protected String handleEdit(HttpServletRequest request, HttpServletResponse response, Integer id) throws Exception {
		if (null == id) {
			Order entity = new Order();
			entity.setObjectId(orderManager.createSystemId());
			request.setAttribute("entity", entity);
		}
		request.setAttribute("units", dictionaryFacade.getDictionariesByDictionaryId(1008));
		request.setAttribute("template", ApplicationConfig.getTemplate());
		return super.handleEdit(request, response, id);
	}

	protected String handleSave(HttpServletRequest request, ModelMap modelMap, Order order) throws Exception {
		if (order.getId() == null) {
			order.setSalesId(FrameworkContextUtils.getCurrentUserId());
			order.setOrderDate(new Date());
			order.setFinanceStatus(Order.ORDER_FINANCE_STATUS_UNPAY);
		}
		getEntityManager().save(order);
		if (order.getStatus() == Order.ORDER_STATUS_COMMIT) {
			List<User> users = cUserManager.getNoticeUsers(UserNotice.TYPE_ORDER_APPROVAL);
			if (users.size() > 0) {
				String subject = "订单提交通知(" + order.getOrderNo() + ")";
				String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getOrderNo() + "的订单已提交，请您登录<a href='"
				        + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName() + "</a>审批。<br/>"
				        + ProjectUtils.getCommonNoReplyMessage();
				for (User user : users) {
					try {
						notificationManager.sendMail(subject, user.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(user.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendOrderApprovalMessages", e);
					}
				}
			}
		}
		return "redirect:edit/" + ((BaseEntity) order).getId() + getMessage("common.base.success", request) + "&action="
		        + request.getParameter("action");
	}

	@RequestMapping("my")
	public String my(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_salesId", FrameworkContextUtils.getCurrentUserId() + ""));
		String result = handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "my");
		return result;
	}

	@RequestMapping("unpay")
	public String unpay(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("GEI_status", Order.ORDER_STATUS_APPROVED + ""));
		page.getFilters().add(new PropertyFilter("EQI_financeStatus", Order.ORDER_FINANCE_STATUS_UNPAY + ""));
		pageSetting(request);
		orderManager.financeFind(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "unpay");
		return getFileBasePath() + "listOrder";
	}

	@RequestMapping("paid")
	public String paid(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_financeStatus", Order.ORDER_FINANCE_STATUS_PAYED + ""));
		pageSetting(request);
		orderManager.financeFind(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "paid");
		return getFileBasePath() + "listOrder";
	}

	@RequestMapping("pay/{orderId}")
	public String pay(HttpServletRequest request, @PathVariable Integer orderId, ModelMap modelMap) throws Exception {
		boolean result = false;
		if (orderId != null) {
			try {
				Order order = orderManager.getByObjectId(orderId);
				if (order != null && order.getFinanceStatus() == Order.ORDER_FINANCE_STATUS_UNPAY) {
					order.setFinanceStatus(Order.ORDER_FINANCE_STATUS_PAYED);
					order.setPayDate(new Date());
					orderManager.save(order);
				}
				result = true;
			} catch (Exception e) {
				LOGGER.error("pay:" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("finish/{orderId}")
	public String finish(HttpServletRequest request, @PathVariable Integer orderId, ModelMap modelMap) throws Exception {
		boolean result = false;
		if (orderId != null) {
			try {
				Order order = orderManager.getByObjectId(orderId);
				if (order != null && order.getStatus() != Order.ORDER_STATUS_FINISHED) {
					order.setStatus(Order.ORDER_STATUS_FINISHED);
					orderManager.save(order);
				}
				result = true;
			} catch (Exception e) {
				LOGGER.error("finish" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("audit")
	public String audit(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_status", Order.ORDER_STATUS_COMMIT + ""));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "audit");
		return getFileBasePath() + "listOrder";
	}

	@RequestMapping("audit/{orderId}")
	public String audit(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer orderId) {
		boolean result = false;
		if (orderId != null) {
			try {
				Order order = orderManager.getByObjectId(orderId);
				if (order.getStatus() == Order.ORDER_STATUS_COMMIT) {
					order.setStatus(Order.ORDER_STATUS_APPROVED);
					order.setAppovalUserId(FrameworkContextUtils.getCurrentUserId());
					order.setAuditDate(new Date());
					orderManager.save(order);
					User applier = userManager.getByObjectId(order.getSalesId());
					String subject = "订单审批完成通知(" + order.getOrderNo() + ")";
					String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getOrderNo() + "的订单已审批，请您登录<a href='"
					        + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName() + "</a>查看详情。<br/>"
					        + ProjectUtils.getCommonNoReplyMessage();
					try {
						notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
						        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
					} catch (Exception e) {
						LOGGER.error("sendOrderApprovedMessages", e);
					}
					result = true;
				}
			} catch (Exception e) {
				LOGGER.error("audit" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("backward/{orderId}")
	public String backward(HttpServletRequest request, ModelMap modelMap, @PathVariable Integer orderId) {
		boolean result = false;
		if (orderId != null) {
			try {
				if (orderManager.canBackward(orderId)) {
					Order order = orderManager.getByObjectId(orderId);
					if (order.getStatus() == Order.ORDER_STATUS_APPROVED) {
						String reason = request.getParameter("reason");
						order.setStatus(Order.ORDER_STATUS_BACKWARD);
						order.setAppovalUserId(null);
						order.setAuditDate(null);
						order.setBackwardReason(reason);
						orderManager.save(order);
						User applier = userManager.getByObjectId(order.getSalesId());
						String subject = "订单审批退回通知(" + order.getOrderNo() + ")";
						String content = "，您好：<br/>" + ProjectUtils.getParagraphIndent() + "编号为" + order.getOrderNo() + "的订单已退回，原因为："
						        + reason + "。请您登录<a href='" + DomainUtils.getDynamicDomain() + "'>" + ApplicationConfig.getSystemName()
						        + "</a>查看详情。<br/>" + ProjectUtils.getCommonNoReplyMessage();
						try {
							notificationManager.sendMail(subject, applier.getUserName() + content, new File[] {}, new String[] {},
							        ProjectUtils.getMailTo(applier.getEmail()), new String[] {}, false);
						} catch (Exception e) {
							LOGGER.error("sendOrderBackwardMessages", e);
						}
						result = true;
					}
				} else {
					modelMap.addAttribute("message", "已经装箱或开发票了，不能再修改。");
				}
			} catch (Exception e) {
				LOGGER.error("backward" + orderId, e);
			}
		}
		modelMap.put("result", result);
		return "jsonView";
	}

	@RequestMapping("print/{orderId}")
	public String print(HttpServletRequest request, @PathVariable Integer orderId) {
		Map<String, Object> model = prepareOrderData(orderId, request);
		String orderContent = notificationManager.getTemplateString("order" + ApplicationConfig.getTemplate() + ".html", model);
		request.setAttribute("orderContent", orderContent);
		return getFileBasePath() + "printOrder";
	}

	@RequestMapping("selectToPurchase")
	public String selectToPurchase(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		page.getFilters().add(new PropertyFilter("EQI_status", Order.ORDER_STATUS_APPROVED + ""));
		handlePage(request, page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "selectToPurchase");
		return getFileBasePath() + "selectOrder";
	}

	@RequestMapping("selectToPacking")
	public String selectToPacking(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		if (StringUtils.isNotBlank(request.getParameter("customerId"))) {
			page.getFilters().add(new PropertyFilter("EQI_customerId", request.getParameter("customerId")));
		}
		page.getFilters().add(new PropertyFilter("EQI_status", Order.ORDER_STATUS_APPROVED + ""));
		pageSetting(request);
		orderManager.findForPackingImport(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "selectToPacking");
		return getFileBasePath() + "selectPackingOrder";
	}

	@RequestMapping("selectToCommercialInvoice")
	public String selectToCommercialInvoice(HttpServletRequest request, HttpServletResponse response) throws Exception {
		Limit limit = PageUtils.getLimit(request);
		PageSearch page = preparePage(request, limit);
		if (StringUtils.isNotBlank(request.getParameter("customerId"))) {
			page.getFilters().add(new PropertyFilter("EQI_customerId", request.getParameter("customerId")));
		}
		page.getFilters().add(new PropertyFilter("EQI_status", Order.ORDER_STATUS_APPROVED + ""));
		String from = request.getParameter("from");
		if (from != null && from.equals("my")) {
			page.getFilters().add(new PropertyFilter("EQI_salesId", FrameworkContextUtils.getCurrentUserId() + ""));
			request.setAttribute("from", from);
		}
		pageSetting(request);
		orderManager.findForCommercialInvoiceImport(page);
		afterPage(request, page, IS_NOT_BACK);
		request.setAttribute("action", "selectToCommercialInvoice");
		return getFileBasePath() + "selectPackingOrder";
	}

	@RequestMapping("get/{orderId}")
	public String get(ModelMap modelMap, @PathVariable Integer orderId) throws Exception {
		Order order = orderManager.getObject(orderId);
		modelMap.addAttribute("order", order);
		return "jsonView";
	}

	@RequestMapping("getCustomer/{orderId}")
	public String getCustomer(ModelMap modelMap, @PathVariable Integer orderId) throws Exception {
		Order order = orderManager.getObject(orderId);
		modelMap.addAttribute("entity", order.getCustomer());
		return "jsonView";
	}

	@RequestMapping("notify/{orderId}")
	public String notify(@PathVariable Integer orderId, String purchasers, Boolean customer, ModelMap modelMap, HttpServletRequest request) {
		boolean result = false;
		try {
			String userEmails = purchasers;
			userEmails += ProjectUtils.EMAIL_SPLIT + request.getParameter("others");
			if (StringUtils.isNotBlank(userEmails) || customer) {
				Map<String, Object> model = prepareOrderData(orderId, request);
				String orderContent = notificationManager.getTemplateString("order" + ApplicationConfig.getTemplate() + ".html", model);
				Order order = (Order) model.get("entity");
				if (customer) {
					userEmails += ProjectUtils.EMAIL_SPLIT + order.getCustomer().getEmail();
				}
				String[] to = ProjectUtils.getMailTo(userEmails);
				if (to != null && to.length > 0) {
					Company company = order.getCompany();
					String header = ProjectUtils.getPdfHeader(company);
					String footer = ProjectUtils.getPdfFooter(company);
					File file = PdfUtils.htmlToPdf(orderContent, header, footer);
					String subject = "Order Confirm(" + company.getName() + ":" + order.getOrderNo() + ")";
					notificationManager.sendMail(subject, ProjectUtils.getENNoReplyMessage(), new File[] { file },
					        new String[] { order.getOrderNo() + ".pdf" }, to, new String[] {}, true);
					result = true;
				}
			}
		} catch (Exception e) {
			LOGGER.error("notify", e);
		}
		modelMap.addAttribute("result", result);
		return "jsonView";
	}

	@RequestMapping("download/{orderId}")
	public String download(@PathVariable Integer orderId, HttpServletRequest request, HttpServletResponse response) {
		try {
			Map<String, Object> model = prepareOrderData(orderId, request);
			String orderContent = notificationManager.getTemplateString("order" + ApplicationConfig.getTemplate() + ".html", model);
			Order order = (Order) model.get("entity");
			Company company = order.getCompany();
			String header = ProjectUtils.getPdfHeader(company);
			String footer = ProjectUtils.getPdfFooter(company);
			File file = PdfUtils.htmlToPdf(orderContent, header, footer);
			FileUpDownUtils.setDownloadResponseHeaders(response, order.getOrderNo() + ".pdf");
			FileUpDownUtils.downloadFile(file, response);
		} catch (Exception e) {
			LOGGER.error("download", e);
		}
		return null;
	}

	protected Map<String, Object> prepareOrderData(Integer orderId, HttpServletRequest request) {
		Order order = orderManager.getObject(orderId);
		Map<String, Object> model = new HashMap<String, Object>();
		model.put("entity", order);
		model.put("orderItems", order.getOrderItems());
		model.put("orderCharges", order.getCharges());
		model.put("currency", dictionaryFacade.getDictionaryByDictionaryIdAndValue(1006, order.getCurrency()).getName());
		model.put("staticDomain", ProjectUtils.getFullCssThemePath());
		model.put("groupName", ApplicationConfig.getGroupName());
		model.put("fontSize", ApplicationConfig.getFontSize());
		request.setAttribute("fontSize", ApplicationConfig.getFontSize());
		request.setAttribute("entity", order);
		request.setAttribute("currency", dictionaryFacade.getDictionaryByDictionaryIdAndValue(1006, order.getCurrency()).getName());
		request.setAttribute("staticDomain", ProjectUtils.getFullCssThemePath());
		request.setAttribute("groupName", ApplicationConfig.getGroupName());
		if (order.getAppovalUserId() != null) {
			User user = userManager.getByObjectId(order.getAppovalUserId());
			model.put("auditor", user);
			request.setAttribute("auditor", user);
		}
		return model;
	}

	@Override
	public PageManager<Order> getEntityManager() {
		return orderManager;
	}

	@Override
	public String getFileBasePath() {
		return "business/";
	}

}
